/*
 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <ctype.h>
#include <errno.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "mobile_provider.h"

void print_provider(struct mobile_provider *provider)
{
  struct mobile_apn *apn;
  gchar *networks;
  int i, j;
  int num_networks;
  int namelen, maxnamelen;
  int userlen, maxuserlen;
  int passlen, maxpasslen;

  num_networks = g_strv_length(provider->networks);
  printf("\"\033[1;33m%s\033[m\" in country \"\033[1;33m%s\033[m\" has "
           "%d network ID%s and %d APN%s%s\n",
         provider->names[0]->name,
         provider->country,
         num_networks,
         num_networks == 1 ? "" : "s",
         provider->num_apns,
         provider->num_apns == 1 ? "" : "s",
         provider->primary ? " [\033[1;31mprimary\033[m]" : "");
  for (i = 1; i < provider->num_names; i++)
    if (provider->names[i]->lang == NULL)
      printf("  name: %s\n", provider->names[i]->name);
    else
      printf("  name: %s lang: %s\n",
             provider->names[i]->name,
             provider->names[i]->lang);
  networks = g_strjoinv(",", provider->networks);
  printf("  networks: %s\n", networks);
  g_free(networks);
  maxnamelen = -1;
  maxuserlen = maxpasslen = strlen("<none>");
  for (i = 0; i < provider->num_apns; i++) {
    apn = provider->apns[i];
    namelen = strlen(apn->value);
    if (namelen > maxnamelen)
      maxnamelen = namelen;
    if (apn->username && (userlen = strlen(apn->username)) > maxuserlen)
      maxuserlen = userlen;
    if (apn->password && (passlen = strlen(apn->password)) > maxpasslen)
      passlen = passlen;
  }
  if (maxuserlen == -1)
    maxuserlen = strlen("<none>");
  if (maxpasslen == -1)
    maxpasslen = strlen("<none>");
  for (i = 0; i < provider->num_apns; i++) {
    apn = provider->apns[i];
    printf("  APN %d: \033[1;32m%-*s\033[m  username %-*s  password %-*s\n",
           i+1,
           maxnamelen, apn->value,
           maxuserlen, apn->username ? apn->username : "<none>",
           maxpasslen, apn->password ? apn->password : "<none>");
    for (j = 0; j < apn->num_names; j++)
      if (apn->names[j]->lang == NULL)
        printf("    name: %s\n", apn->names[j]->name);
      else
        printf("    name: %s lang; %s\n",
               apn->names[j]->name,
               apn->names[j]->lang);
  }
}

void print_provider_list(struct mobile_provider *provider)
{
  while (provider != NULL) {
    print_provider(provider);
    provider = provider->next;
  }
  printf("---------------------------------------------------------------\n");
}

void print_network(gchar *network, struct mobile_provider *provider)
{
  printf("[%s]: ", network);
  print_provider(provider);
  printf("---------------------------------------------------------------\n");
}

int main(int argc, const char *argv[])
{
  char linebuf[BUFSIZ];
  char *line;
  struct mobile_provider *provider;
  struct mobile_provider_db *provider_db;

  if (argc < 2) {
    fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
    exit(1);
  }
  provider_db = mobile_provider_open_db(argv[1]);
  if (provider_db == NULL) {
    perror("Cannot open provider database");
    exit(1);
  }
  while (1) {
    int linelen;
    printf("Type a network ID or provider name: ");
    line = fgets(linebuf, sizeof(linebuf), stdin);
    if (line == NULL || line[0] == '\n')
      break;
    linelen = strlen(line);
    if (line[linelen-1] == '\n')
      line[--linelen] = '\0';
    if ((linelen == 5 || linelen == 6) &&
        isdigit(line[0]) && isdigit(line[1]) && isdigit(line[linelen-1])) {
      provider = mobile_provider_lookup_by_network(provider_db,
                                                   line);
      if (provider != NULL)
        print_provider(provider);
    } else if (line[0] == '*') {
      if (line[1] == 'p')
        mobile_provider_foreach_provider(provider_db,
                                         print_provider_list);
      else if (line[1] == 'n')
        mobile_provider_foreach_network(provider_db,
                                        print_network);
      else
        printf("error: Unknown command \"%s\"\n", line);
      continue;
    } else {
      provider = mobile_provider_lookup_by_name(provider_db,
                                                line);
      if (provider != NULL)
        print_provider_list(provider);
    }
    if (provider == NULL)
      printf("No provider found for %s\n", line);
  }
  mobile_provider_close_db(provider_db);
  return 0;
}
